package com.sduept.nwld.dataserver.controller.ledger;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.PostConstruct;
import javax.faces.view.ViewScoped;
import javax.inject.Named;

import org.apache.commons.lang3.StringUtils;
import org.primefaces.PrimeFaces;
import org.primefaces.event.SelectEvent;
import org.primefaces.model.DefaultStreamedContent;
import org.primefaces.model.LazyDataModel;
import org.primefaces.model.SortOrder;
import org.primefaces.model.StreamedContent;
import org.springframework.beans.factory.annotation.Autowired;

import com.sduept.bigdata.document.core.CommonDocumentProperties;
import com.sduept.bigdata.web.jsf.controller.AbstractController;
import com.sduept.cim.ledger.manager.LineSegmentLedgerManager;
import com.sduept.cim.ledger.model.ManagementUnitDict;
import com.sduept.cim.ledger.model.PrimaryEquipmentLedger;
import com.sduept.cim.model.wires.ACLineSegment;
import com.sduept.cim.model.wires.DcLinesegment;
import com.sduept.bigdata.weather.map.MapDataCache;
import com.sduept.nwld.dataserver.manager.cim.CimManager;

/**
 * 一次设备（直流线路、交流线路）台账信息查看
 *
 * @author hy
 */

@Named
@ViewScoped
public class LineSegmentLedgerController extends AbstractController {

    private static final long serialVersionUID = 7086308769325531944L;
    @Autowired
    private CommonDocumentProperties pros;
    @Autowired
    private LineSegmentLedgerManager lineLedgerM;
    @Autowired
    private CimManager cimM;
    @Autowired
    private MapDataCache cc;

    private LazyDataModel<PrimaryEquipmentLedger> aclineModel;
    private LazyDataModel<PrimaryEquipmentLedger> dclineModel;
    private long rowCount = 0;
    private long rowCount1 = 0;

    private List<PrimaryEquipmentLedger> selectedLineledgerList = new ArrayList<PrimaryEquipmentLedger>();
    private PrimaryEquipmentLedger editLedger = new PrimaryEquipmentLedger();
    private PrimaryEquipmentLedger queryLedger = new PrimaryEquipmentLedger();

    /**
     * 查询条件
     */
    private String equipmentName = null; // 设备名称
    private String selectdStandVolLevel = "500";  //电压等级默认为500

    private StreamedContent templateFile;

    @PostConstruct
    public void init() {
        initTable();
        PrimeFaces.current().executeScript("rc()");
    }

    public void initAllDate() {
        List<PrimaryEquipmentLedger> ledgerList = lineLedgerM.findAllPrimaryEquipmentLedger();
        if (ledgerList.size() == 0) {
            try {
                lineLedgerM.initLineEquipment();
            } catch (SQLException e) {
                addErrorMessage("初始化数据失败");
            }
            initTable();
        } else {
            alertErrorMessage("已有数据，不允许重新初始化！");
        }
    }

    public void execute() {
        initAcLineTable();
    }

    public void query() {
        initTable();
    }

    private void initTable() {
        initAcLineTable();
        initDcLineTable();
    }

    /**
     * 当查询参数为空时，与查询参数取值为“未设置”相同
     * 当仅有部分查询参数有值时，未设置值的参数应该默认查询全部
     * 注：当变电站名称不为空时，默认其他选择的参数无效，即进按照变电站名称进行查询
     */
    private void resetParamBeforeQuery() {
        // 如果变电站名称不为空，则查找条件仅变电站名称有效，即仅按照变电站名称进行查询
        if (StringUtils.isNotEmpty(equipmentName)) {
            queryLedger.setDispatchUnit("全部");
            queryLedger.setMaintenanceUnit("全部");
            queryLedger.setAssetOwner("全部");
            queryLedger.setPrimaryEquipmentScope("全部");
            queryLedger.setSecondaryEquipmentScope("全部");
        } else {
            // 变电站名称为空时
            int i = 0;
            if (StringUtils.isNotEmpty(queryLedger.getDispatchUnit())) {
                i++;
            }
            if (StringUtils.isNotEmpty(queryLedger.getMaintenanceUnit())) {
                i++;
            }
            if (StringUtils.isNotEmpty(queryLedger.getAssetOwner())) {
                i++;
            }
            if (StringUtils.isNotEmpty(queryLedger.getPrimaryEquipmentScope())) {
                i++;
            }
            if (StringUtils.isNotEmpty(queryLedger.getSecondaryEquipmentScope())) {
                i++;
            }
            if (i > 0 && i < 5) {
                // 有空的查询参数，有有值的查询参数，此时，需要将空参数全部变为全部
                if (StringUtils.isEmpty(queryLedger.getDispatchUnit())) {
                    queryLedger.setDispatchUnit("全部");
                }
                if (StringUtils.isEmpty(queryLedger.getMaintenanceUnit())) {
                    queryLedger.setMaintenanceUnit("全部");
                }
                if (StringUtils.isEmpty(queryLedger.getAssetOwner())) {
                    queryLedger.setAssetOwner("全部");
                }
                if (StringUtils.isEmpty(queryLedger.getPrimaryEquipmentScope())) {
                    queryLedger.setPrimaryEquipmentScope("全部");
                }
                if (StringUtils.isEmpty(queryLedger.getSecondaryEquipmentScope())) {
                    queryLedger.setSecondaryEquipmentScope("全部");
                }
            }
        }
    }

    private void initAcLineTable() {
        aclineModel = new LazyDataModel<PrimaryEquipmentLedger>() {
            List<PrimaryEquipmentLedger> aclineList = new ArrayList<PrimaryEquipmentLedger>();
            private static final long serialVersionUID = 6065820294430715275L;

            @Override
            public List<PrimaryEquipmentLedger> load(int first, int pageSize, String sortField, SortOrder sortOrder, Map<String, Object> filters) {
                resetParamBeforeQuery();
                aclineList = lineLedgerM.queryAcLineLedger(selectdStandVolLevel, equipmentName, queryLedger, new int[]{first, first + pageSize});
                return aclineList;
            }

            @Override
            public PrimaryEquipmentLedger getRowData(String rowKey) {
                for (PrimaryEquipmentLedger primaryEquipmentLedger : aclineList) {
                    if (rowKey.equals(primaryEquipmentLedger.getId())) {
                        return primaryEquipmentLedger;
                    }
                }
                return null;
            }

            @Override
            public Object getRowKey(PrimaryEquipmentLedger object) {
                for (PrimaryEquipmentLedger primaryEquipmentLedger : aclineList) {
                    if (primaryEquipmentLedger.getId().equals(object.getId())) {
                        return primaryEquipmentLedger;
                    }
                }
                return null;
            }
        };
        resetParamBeforeQuery();
        rowCount = lineLedgerM.countAcLineLedger(selectdStandVolLevel, equipmentName, queryLedger);
        aclineModel.setRowCount((int) rowCount);
    }

    private void initDcLineTable() {
        dclineModel = new LazyDataModel<PrimaryEquipmentLedger>() {
            private static final long serialVersionUID = 6065820294430715275L;
            List<PrimaryEquipmentLedger> dclineList = new ArrayList<PrimaryEquipmentLedger>();

            @Override
            public List<PrimaryEquipmentLedger> load(int first, int pageSize, String sortField, SortOrder sortOrder, Map<String, Object> filters) {
                resetParamBeforeQuery();
                dclineList = lineLedgerM.queryDcLineLedger(selectdStandVolLevel, equipmentName, queryLedger, new int[]{first, first + pageSize});
                return dclineList;
            }

            @Override
            public PrimaryEquipmentLedger getRowData(String rowKey) {
                for (PrimaryEquipmentLedger primaryEquipmentLedger : dclineList) {
                    if (rowKey.equals(primaryEquipmentLedger.getId())) {
                        return primaryEquipmentLedger;
                    }
                }
                return null;
            }

            @Override
            public Object getRowKey(PrimaryEquipmentLedger object) {
                for (PrimaryEquipmentLedger primaryEquipmentLedger : dclineList) {
                    if (primaryEquipmentLedger.getId().equals(object.getId())) {
                        return primaryEquipmentLedger;
                    }
                }
                return null;
            }
        };
        resetParamBeforeQuery();
        rowCount1 = lineLedgerM.countDcLineLedger(selectdStandVolLevel, equipmentName, queryLedger);
        dclineModel.setRowCount((int) rowCount1);
    }

    /**
     * 编辑时，当仅选中一条记录时，显示该记录的信息，当选中多条记录时，仅显示变电站名称
     */
    public void preEdit() {
        if (selectedLineledgerList.size() == 1) {
            editLedger = selectedLineledgerList.get(0);
            if (StringUtils.isEmpty(editLedger.getAssetOwner())) {
                // 默认资产归属为南网
                editLedger.setAssetOwner("南网");
            }
        } else {
            editLedger.setAssetOwner("南网");
        }
    }

    public void save() {
        for (PrimaryEquipmentLedger ledger : selectedLineledgerList) {
            ledger.setAssetOwner(editLedger.getAssetOwner());
            ledger.setDispatchUnit(editLedger.getDispatchUnit());
            ledger.setDispatchUnitId(editLedger.getDispatchUnitId());
            ledger.setMaintenanceUnit(editLedger.getMaintenanceUnit());
            ledger.setMaintenanceUnitId(editLedger.getMaintenanceUnitId());
            ledger.setUnitType(editLedger.getUnitType());
            ledger.setPrimaryEquipmentScope(editLedger.getPrimaryEquipmentScope());
            ledger.setPrimaryEquipmentScopeRemark(editLedger.getPrimaryEquipmentScopeRemark());
            ledger.setSecondaryEquipmentScope(editLedger.getSecondaryEquipmentScope());
            ledger.setSecondaryEquipmentScopeRemark(editLedger.getSecondaryEquipmentScopeRemark());
        }
        try {
            lineLedgerM.savePrimaryLedgers(selectedLineledgerList);
            addSuccessMessage("保存成功！");
        } catch (SQLException e) {
            addErrorMessage("保存失败");
        }
        selectedLineledgerList.clear();
    }

    public void resetQueryCondition() {
        equipmentName = null;
        queryLedger = new PrimaryEquipmentLedger();
        selectdStandVolLevel = "500";
        initTable();
    }

    /**
     * 清空选中线路的所有单位设置（调管单位、运维单位、资产归属、一|二次设备检查范围等）
     */
    public void cleanLedgers() {
        if (selectedLineledgerList.size() > 0) {
            for (PrimaryEquipmentLedger entity : selectedLineledgerList) {
                entity.setAssetOwner(null);
                entity.setDispatchUnit(null);
                entity.setMaintenanceUnit(null);
                entity.setPrimaryEquipmentScope(null);
                entity.setPrimaryEquipmentScopeRemark(null);
                entity.setSecondaryEquipmentScope(null);
                entity.setSecondaryEquipmentScopeRemark(null);
                entity.setUnitType(null);
            }
            try {
                lineLedgerM.savePrimaryLedgers(selectedLineledgerList);
                selectedLineledgerList.clear();
                addSuccessMessage("清除成功");
            } catch (SQLException e) {
                addErrorMessage("清除失败");
            }
        }
    }

    /**
     * 模板下载
     */
    public void fileDownloadView() {
        InputStream stream = null;
        try {
            stream = new FileInputStream(new File(pros.getTempletePath() + "equipmentLedger.xlsx"));
            setTemplateFile(new DefaultStreamedContent(stream, "xlsx", "equipmentLedger.xlsx"));
        } catch (FileNotFoundException e) {
            addErrorMessage("下载文件失败，请联系技术人员！");
            e.printStackTrace();
        }
    }

    public void openUploadDialog() {
        Map<String, Object> options = new HashMap<String, Object>();
        options.put("resizable", true);
        options.put("draggable", true);
        options.put("modal", true);
        options.put("width", 600);
        options.put("height", 200);
        Map<String, List<String>> params = new HashMap<>();
        List<String> param = new ArrayList<>();
        param.add("1");    //设置去除前几行
        params.put("ingnoreRows", param);
        openDialog("/ui/common/upload_excel_define", params, options);
    }

    /**
     * 文件上传
     *
     * @param event
     */
    // 0线路id  1线路名称  2调度单位	 3运维单位  4单位类型	5资产归属	6一次设备检修范围   7一次设备检修范围备注	8二次设备检修范围	9二次设备检修范围备注
    public void onSelectorChosen(SelectEvent event) {
        Map<String, PrimaryEquipmentLedger> ledgerMap = getAllLedgerMap();
        List<List<String>> objs = (List<List<String>>) event.getObject();
        List<Integer> errorList = new ArrayList<Integer>();
        List<PrimaryEquipmentLedger> ledgerList = new ArrayList<PrimaryEquipmentLedger>();
        Map<String, ACLineSegment> acMap = cc.getAclineid_map();
        Map<String, DcLinesegment> dcMap = cc.getDclineid_map();
        try {
            int rowIndex = 0;
            for (List<String> list : objs) {
                // 当上传数据不完整时，用空值填充list
                if (list.size() < 10) {
                    for (int i = list.size(); i < 11; i++) {
                        list.add("");
                    }
                }
                rowIndex++;
                PrimaryEquipmentLedger ledger = new PrimaryEquipmentLedger();
                ACLineSegment acline = acMap.get(list.get(0));
                if (null != acline) {
                    ledger = setLedgerAttr(list, "交流线路", ledgerMap);
                    ledgerList.add(ledger);
                } else {
                    DcLinesegment dcline = dcMap.get(list.get(0));
                    if (null != dcline) {
                        ledger = setLedgerAttr(list, "直流线路", ledgerMap);
                        ledgerList.add(ledger);
                    } else {
                        errorList.add(rowIndex);
                    }
                }
            }
            if (ledgerList.size() > 0) {
                for (PrimaryEquipmentLedger ledger : ledgerList) {
                    lineLedgerM.createOrUpdatePrimaryEquipmentLedger(ledger);
                }
                addSuccessMessage("文件上传成功！");
            }
            StringBuffer sb = new StringBuffer();
            if (errorList.size() != 0) {
                sb.append("上传的文件中，第：");
                for (Integer i : errorList) {
                    sb.append(i + "、");
                }
                sb.append("行线路Id不存在，请核实后再次上传！");
                alertErrorMessage(sb + "");
            }
        } catch (Exception e) {
            e.printStackTrace();
            addErrorMessage("表格数字有误，请仔细核对！");
            return;
        }
        initTable();
    }

    /**
     * 获取所有的PrimaryEquipmentLedger，用来判断当前上传的线路id是否已经存在对应的PrimaryEquipmentLedger实体
     */
    private Map<String, PrimaryEquipmentLedger> getAllLedgerMap() {
        Map<String, PrimaryEquipmentLedger> ledgerMap = new HashMap<String, PrimaryEquipmentLedger>();
        List<PrimaryEquipmentLedger> allLedgers = lineLedgerM.findAllPrimaryEquipmentLedger();
        for (PrimaryEquipmentLedger ledger : allLedgers) {
            ledgerMap.put(ledger.getCimId(), ledger);
        }
        return ledgerMap;
    }

    /**
     * 设置PrimaryEquipmentLedger的各属性
     */
    // 0线路id  1线路名称  2调度单位	 3运维单位  4单位类型	5资产归属	6一次设备检修范围   7一次设备检修范围备注	8二次设备检修范围	9二次设备检修范围备注
    private PrimaryEquipmentLedger setLedgerAttr(List<String> list, String equpitType, Map<String, PrimaryEquipmentLedger> ledgerMap) {
        PrimaryEquipmentLedger ledger = ledgerMap.get(list.get(0));
        if (null == ledger) {
            ledger = new PrimaryEquipmentLedger();
        }
        ledger.setCimId(list.get(0));
        ledger.setEquipmentType(equpitType);
        ledger.setName(list.get(1));
        ledger.setDispatchUnit(list.get(2));
        // TODO
        ledger.setDispatchUnitId(null);
        ledger.setUnitType(list.get(4));
        ledger.setAssetOwner(list.get(5));
        ledger.setPrimaryEquipmentScopeRemark(list.get(7));
        ledger.setSecondaryEquipmentScopeRemark(list.get(9));

        // 3运维单位、6一次设备检修范围、8二次设备检修范围三个的数值是一样的
        String sameValue = "";
        if (StringUtils.isNotEmpty(list.get(8))) {
            sameValue = list.get(8);
        }
        if (StringUtils.isNotEmpty(list.get(6))) {
            sameValue = list.get(6);
        }
        if (StringUtils.isNotEmpty(list.get(3))) {
            sameValue = list.get(3);
        }
        ledger.setMaintenanceUnit(StringUtils.isNotEmpty(list.get(3)) ? list.get(3) : sameValue);
        // TODO
        ledger.setMaintenanceUnitId(null);
        ledger.setPrimaryEquipmentScope(StringUtils.isNotEmpty(list.get(6)) ? list.get(6) : sameValue);
        ledger.setSecondaryEquipmentScope(StringUtils.isNotEmpty(list.get(8)) ? list.get(8) : sameValue);
        return ledger;
    }

    /**
     * 选择调度部门后，设置PrimaryEquipmentLedger的对应值
     *
     * @param event
     */
    public void onDesorgDepartChosen(SelectEvent event) {
        ManagementUnitDict dept = (ManagementUnitDict) event.getObject();
        editLedger.setDispatchUnit(dept.getName());
        editLedger.setDispatchUnitId(dept.getId());
    }

    /**
     * 选择运维部门后，设置PrimaryEquipmentLedger的对应值
     *
     * @param event
     */
    public void onOpDepartChosen(SelectEvent event) {
        ManagementUnitDict dept = (ManagementUnitDict) event.getObject();
        editLedger.setMaintenanceUnit(dept.getName());
        editLedger.setMaintenanceUnitId(dept.getId());
        if (dept.getName().contains("超高压")) {
            editLedger.setUnitType("超高压分局");
        } else if (dept.getName().contains("供电局")) {
            editLedger.setUnitType("供电局");
        } else if (dept.getName().contains("电厂")) {
            editLedger.setUnitType("发电厂");
        } else {
            editLedger.setUnitType(null);
        }
    }

    /**
     * 选择一次设备检修范围
     *
     * @param event
     */
    public void onPrimaryScopeChosen(SelectEvent event) {
        ManagementUnitDict dept = (ManagementUnitDict) event.getObject();
        editLedger.setPrimaryEquipmentScope(dept.getName());
    }

    /**
     * 选择二次设备检修范围
     *
     * @param event
     */
    public void onSecondryScopeChosen(SelectEvent event) {
        ManagementUnitDict dept = (ManagementUnitDict) event.getObject();
        editLedger.setSecondaryEquipmentScope(dept.getName());
    }

    public StreamedContent getTemplateFile() {
        return templateFile;
    }

    public void setTemplateFile(StreamedContent templateFile) {
        this.templateFile = templateFile;
    }

    public LazyDataModel<PrimaryEquipmentLedger> getAclineModel() {
        return aclineModel;
    }

    public void setAclineModel(LazyDataModel<PrimaryEquipmentLedger> aclineModel) {
        this.aclineModel = aclineModel;
    }

    public LazyDataModel<PrimaryEquipmentLedger> getDclineModel() {
        return dclineModel;
    }

    public void setDclineModel(LazyDataModel<PrimaryEquipmentLedger> dclineModel) {
        this.dclineModel = dclineModel;
    }

    public long getRowCount() {
        return rowCount;
    }

    public void setRowCount(long rowCount) {
        this.rowCount = rowCount;
    }

    public long getRowCount1() {
        return rowCount1;
    }

    public void setRowCount1(long rowCount1) {
        this.rowCount1 = rowCount1;
    }

    public List<PrimaryEquipmentLedger> getSelectedLineledgerList() {
        return selectedLineledgerList;
    }

    public void setSelectedLineledgerList(List<PrimaryEquipmentLedger> selectedLineledgerList) {
        this.selectedLineledgerList = selectedLineledgerList;
    }

    public PrimaryEquipmentLedger getEditLedger() {
        return editLedger;
    }

    public void setEditLedger(PrimaryEquipmentLedger editLedger) {
        this.editLedger = editLedger;
    }

    public PrimaryEquipmentLedger getQueryLedger() {
        return queryLedger;
    }

    public void setQueryLedger(PrimaryEquipmentLedger queryLedger) {
        this.queryLedger = queryLedger;
    }

    public String getEquipmentName() {
        return equipmentName;
    }

    public void setEquipmentName(String equipmentName) {
        this.equipmentName = equipmentName;
    }

    public String getSelectdStandVolLevel() {
        return selectdStandVolLevel;
    }

    public void setSelectdStandVolLevel(String selectdStandVolLevel) {
        this.selectdStandVolLevel = selectdStandVolLevel;
    }

}
